
package com.jf.cloud.seckill.controller.app;

import com.jf.cloud.api.platform.feign.ConfigFeignClient;
import com.jf.cloud.api.product.feign.SkuFeignClient;
import com.jf.cloud.api.product.feign.SpuFeignClient;
import com.jf.cloud.common.constant.ConfigNameConstant;
import com.jf.cloud.common.constant.StatusEnum;
import com.jf.cloud.common.exception.LuckException;
import com.jf.cloud.common.product.vo.SpuVO;
import com.jf.cloud.common.product.vo.app.SkuAppVO;
import com.jf.cloud.common.response.ResponseEnum;
import com.jf.cloud.common.response.ServerResponseEntity;
import com.jf.cloud.common.util.Json;
import com.jf.cloud.seckill.dto.SeckillDTO;
import com.jf.cloud.seckill.service.SeckillService;
import com.jf.cloud.seckill.service.SeckillSkuService;
import com.jf.cloud.seckill.vo.*;
import io.swagger.v3.oas.annotations.tags.Tag;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.Parameters;
import io.swagger.v3.oas.annotations.Operation;
import ma.glasnost.orika.MapperFacade;
import org.springdoc.api.annotations.ParameterObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;


/**
 * 秒杀信息
 *
 * @author zz
 * @date 2021-04-12 09:36:59
 */
@RestController("appSeckillController")
@RequestMapping("/ua/seckill")
@Tag(name = "app-秒杀活动信息")
public class SeckillController {

    @Autowired
    private SeckillService seckillService;

    @Autowired
    private MapperFacade mapperFacade;

    @Autowired
    private ConfigFeignClient configFeignClient;

    @Autowired
    private SpuFeignClient spuFeignClient;

    @Autowired
    private SeckillSkuService seckillSkuService;

    @Autowired
    private SkuFeignClient skuFeignClient;

    @GetMapping("/page")
    @Operation(summary = "获取首页秒杀信息" , description = "获取首页秒杀信息")
    public ServerResponseEntity<AppSeckillVO> page(@ParameterObject SeckillDTO seckillDTO) {
        seckillDTO.setStatus(StatusEnum.ENABLE.value());
        AppSeckillVO appSeckillVO = seckillService.pageBySelectLot(seckillDTO);
        return ServerResponseEntity.success(appSeckillVO);
    }

    @GetMapping("/prod" )
    @Operation(summary = "获取秒杀商品信息" , description = "根据商品id，获取当前秒杀的商品信息")
    @Parameters({
            @Parameter(name = "seckillId", description = "秒杀id" , required = true),
    })
    public ServerResponseEntity<AppSeckillSpuVO> getSeckill(Long seckillId) {
        if (Objects.isNull(seckillId)) {
            throw new LuckException("该秒杀活动已过期");
        }

        // 秒杀活动信息（来自缓存）
        SeckillVO seckill = seckillService.getBySeckillId(seckillId);

        // 前端看到这个状态码的时候，不用渲染活动页面了
        if (seckill == null || !Objects.equals(seckill.getStatus(), StatusEnum.ENABLE.value()) || seckill.getEndTime().getTime() < System.currentTimeMillis()) {
            return ServerResponseEntity.fail(ResponseEnum.ACTIVITY_END);
        }

        // 秒杀活动sku信息（来自缓存）
        List<SeckillSkuVO> seckillSkus = seckillSkuService.listSeckillSkuBySeckillId(seckill.getSeckillId());

        // 商品信息（来自缓存）
        SpuVO spuVO = spuFeignClient.getDetailById(seckill.getSpuId()).getData();

        // 商品sku信息（来自缓存）
        List<SkuAppVO> skuAppVO = skuFeignClient.listBySpuId(seckill.getSpuId()).getData();
        Integer totalStock = 0;

        List<AppSeckillSkuVO> seckillSkusVO = new ArrayList<>();
        for(SeckillSkuVO seckillSku : seckillSkus) {
            AppSeckillSkuVO appSeckillSkuVO = new AppSeckillSkuVO();
            for (SkuAppVO sku : skuAppVO) {
                if (!Objects.equals(sku.getSkuId(), seckillSku.getSkuId())) {
                    continue;
                }
                appSeckillSkuVO.setSkuName(sku.getSkuName());
                appSeckillSkuVO.setImgUrl(sku.getImgUrl());
                appSeckillSkuVO.setProperties(sku.getProperties());
                appSeckillSkuVO.setPriceFee(sku.getPriceFee());
                // 如果没有市场价，就用售价当作市场价
                appSeckillSkuVO.setMarketPriceFee(Objects.equals(sku.getMarketPriceFee(), 0L) ? sku.getPriceFee():sku.getMarketPriceFee());

                appSeckillSkuVO.setSkuId(sku.getSkuId());
                appSeckillSkuVO.setSeckillId(seckill.getSeckillId());
                Integer stock = seckillSkuService.getStockBySeckillSkuId(seckillSku.getSeckillSkuId());
                totalStock += stock;
                appSeckillSkuVO.setStock(stock);
                appSeckillSkuVO.setSeckillPrice(seckillSku.getSeckillPrice());
                appSeckillSkuVO.setSeckillSkuId(seckillSku.getSeckillSkuId());
            }
            seckillSkusVO.add(appSeckillSkuVO);
        }


        AppSeckillSpuVO seckillSpuVO = mapperFacade.map(seckill, AppSeckillSpuVO.class);
        seckillSpuVO.setShopId(seckill.getShopId());
        seckillSpuVO.setSpuVO(spuVO);
        seckillSpuVO.setSeckillOriginStocks(seckill.getSeckillOriginStocks());
        seckillSpuVO.setMaxNum(seckill.getMaxNum());
        seckillSpuVO.setSeckillTotalStocks(totalStock);
        seckillSpuVO.setSeckillPrice(seckill.getSeckillPrice());
        seckillSpuVO.setSeckillSkuList(seckillSkusVO);

        long now = System.currentTimeMillis();
        int activityStatus = 2;
        Date startTime = seckill.getStartTime();
        // 活动还没开始
        if (startTime.getTime() > now) {
            long residualTime = (startTime.getTime() - now) / 1000;
            // 距离活动开始还有
            seckillSpuVO.setStartIn(residualTime);
            activityStatus = 1;
        }
        // 活动还没结束
        if (seckill.getEndTime().getTime() > now) {
            // 距离活动结束还有
            long residualTime = (seckill.getEndTime().getTime() - now) / 1000;
            seckillSpuVO.setExpiresIn(residualTime);
        }else{
            activityStatus = 3;
        }
        seckillSpuVO.setActivityStatus(activityStatus);
        return ServerResponseEntity.success(seckillSpuVO);
    }


    @GetMapping("/list_seckill_times")
    @Operation(summary = "显示秒杀后台配置信息" , description = "显示秒杀后台配置信息")
    public ServerResponseEntity<SeckillConfigVO> listSeckillTimes() {
        String config = configFeignClient.getConfig(ConfigNameConstant.SECKILL_TIME_CONFIG).getData();
        if(Objects.isNull(config)) {
            return ServerResponseEntity.success();
        }
        SeckillConfigVO seckillConfigVO = Json.parseObject(config, SeckillConfigVO.class);
        return ServerResponseEntity.success(seckillConfigVO);
    }
}
